# 继承
# 定义一个Animal基类，包含动物的基本行为方法
class Animal:
    def eat(self):
        print("吃。。。。。。。")  # 动物吃的行为

    def drink(self):
        print("喝。。。。。。。")  # 动物喝的行为

    def run(self):
        print("跑。。。。。。。")  # 动物跑的行为

    def sleep(self):
        print("睡。。。。。。。")  # 动物睡的行为


# 定义Dog类，继承自Animal类，扩展了狗特有的行为
class Dog(Animal):
    def bark(self):
        print("叫。。。。。。。")  # 狗叫的行为


dog = Dog()
print("狗狗专属：")
dog.eat()
dog.drink()
dog.run()
dog.sleep()
dog.bark()
print("=" * 100)


# 定义Cat类，继承自Animal类，扩展了猫特有的行为
class Cat(Animal):
    def catch(self):
        print("抓。。。。。。。")  # 猫抓的行为


cat = Cat()
print("猫咪专属：")
cat.eat()
cat.drink()
cat.run()
cat.sleep()
cat.catch()
print("=" * 100)


# 定义XiaoTianQuan类，继承自Dog类，扩展了狗的特殊能力
class XiaoTianQuan(Dog):
    def fly(self):
        print("飞。。。。。。。")  # 狗飞的行为，这是天狗的特殊能力

    # 重写哮天犬的叫方法
    # 覆盖式重写
    def bark(self):
        print("嗷嗷嗷。。。。。。。")  # 狗叫的行为，重写了父类的叫方法


xiao_tian_quan = XiaoTianQuan()
print("哮天犬专属：")
xiao_tian_quan.eat()
xiao_tian_quan.drink()
xiao_tian_quan.run()
xiao_tian_quan.sleep()
xiao_tian_quan.bark()
xiao_tian_quan.fly()
print("=" * 100)


class Dog():
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def bark(self):
        print(f"{self.name},{self.age}喜欢汪汪汪。。。。。。。")


class XiaoTianQuan(Dog):
    # 覆盖式重写
    def bark(self):
        print(f"{self.name},年龄是{self.age}，喜欢嗷嗷嗷。。。。。。。")

    # 扩展式重写
    def __init__(self, name, age, magic):
        super().__init__(name, age)
        self.magic = magic

    def fly(self):
        print(f"{self.name},年龄是{self.age}，飞的不错。。。。。。。")

    def __str__(self):
        return f"{self.name}是它的名字,它的年龄是{self.age},它的法力是{self.magic}"


xiao_tian_quan = XiaoTianQuan("大黄", 10, "天鹅之眼")
print(xiao_tian_quan)
xiao_tian_quan.bark()
xiao_tian_quan.fly()
print("=" * 100)


# 多态
# 定义一个Dog类，表示狗狗
class Dog:
    # 定义game方法，表示狗狗玩耍的行为
    def game(self):
        print("狗狗喜欢玩耍。。。。。。。")


# 定义XiaoTianQuan类，继承自Dog类，表示哮天犬
class XiaoTianQuan(Dog):
    # 重写game方法，表示哮天犬特有的玩耍行为
    def game(self):
        print("哮天犬喜欢玩跑酷。。。。。。。")


# 定义person类，表示人
class person:
    # 定义play_with_dog方法，表示人与狗一起玩耍
    # 参数d:Dog，表示传入的狗对象
    def play_with_dog(self, d: Dog):
        print("人喜欢跟狗玩耍。。。。。。。", end=" ")
        d.game()


# 创建Dog类的实例dog
dog = Dog()
# 创建XiaoTianQuan类的实例xiao_tian_quan
xiao_tian_quan = XiaoTianQuan()
# 创建person类的实例p
p = person()
# 调用p的play_with_dog方法，传入dog实例
p.play_with_dog(dog)
# 调用p的play_with_dog方法，传入xiao_tian_quan实例
p.play_with_dog(xiao_tian_quan)
# 打印100个"="符号作为分隔线
print("=" * 100)


# 私有
class Animal:
    def __init__(self, name, age):
        self.name = name
        if age > 0 and age < 150:
            self.__age = age  # 私有属性，只能在类内部访问
        else:
            self.__age = 0  # 私有属性，只能在类内部访问

    def __str__(self):
        return f"{self.name}的年龄是{self.__age}"

    def set_age(self, age):
        if age > 0 and age < 150:
            self.__age = age  # 私有方法，只能在类内部访问
        else:
            print("年龄不合法")


animal = Animal("小白", 10)
print(animal)
# print(animal._Animal__age) # 私有属性只能在类内部访问，所以不能直接访问
animal.set_age(20)  # 调用公有方法，修改私有属性
print(animal)
animal.set_age(200)
print(animal)
print("=" * 100)


class Tools:
    count = 0  # 类属性，所有实例共享

    def __init__(self, name):
        self.name = name
        Tools.count += 1


print(f"当前Tools的实际数量是{Tools.count}")
t1 = Tools("刀")
t2 = Tools("锤子")
t3 = Tools("螺丝刀")
print(f"当前Tools的实际数量是{Tools.count}")
print("=" * 100)


# 方法的划分
# 实例方法：实例对象调用的方法，第一个参数必须是self，表示实例对象本身
# 类方法：类对象调用的方法，第一个参数必须是cls，表示类对象本身
class Tools:
    count = 0  # 类属性，所有实例共享

    def __init__(self, name):
        self.name = name
        Tools.count += 1

    @classmethod
    def show_tool_count(cls):
        return cls.count

    @staticmethod
    def show_tools():
        print("我是工具，我可以做很多事情")


t2 = Tools("锤子")
t3 = Tools("螺丝刀")
t4 = Tools("锉")
t5 = Tools("铁锹")
print(f"当前Tools的实际数量是{Tools.show_tool_count()}")
Tools.show_tools()
print("=" * 100)

import random


# 游戏案例
class Game:
    top_score = 0

    def __init__(self, name):
        self.name = name

    @staticmethod
    def show_help():
        print("游戏帮助")

    @classmethod
    def show_top_score(cls):
        print(f"最高分是{cls.top_score}")

    def start_game(self):
        print(f"{self.name}开始游戏")
        score = random.randint(10, 100)
        print(f"{self.name}的分数是{score}")
        if score > Game.top_score:
            Game.top_score = score
            print(f"{self.name}的最高分更新为{Game.top_score}")


if __name__ == '__main__':
    Game.show_help()
    Game.show_top_score()
    player1 = Game("老王")
    player1.start_game()
    player1.show_top_score()
    player1.start_game()
    player1.show_top_score()
    player1.start_game()
    player1.show_top_score()
print("=" * 100)

# 补充 dir() 可以查看一个对象的所有属性和方法
s1 = "hello world"
print(dir(s1))


class Demo:
    def show(self):
        pass


d = Demo()
print(dir(d))
print("=" * 100)

# 列表推导式
# 生成10个1-20之间的随机数
list = []
for i in range(10):
    list.append(random.randint(1, 20))
print(list)
list = [random.randint(1, 20) for i in range(10)]
print(list)
list = [random.randint(1, 20) for i in range(10) if i % 2 == 0]
print("=" * 100)

dic = {str(i): i ** 2 for i in range(10)}
print(dic)
print("=" * 100)

a = 10
b = 20
if a > b:
    max = a
else:
    max = b
print(max)
print("=" * 100)

max = a if a > b else b  # 三元表达式
print(max)
print("=" * 100)
